import base64
import copy
import hashlib
import time
import urllib.parse

import rsa
from pathlib import Path

import yaml

from lib.setting.setting import TEMP_FILE, BASE_PATH, TEMP_PATH


class HotLoad:
    """
    热加载类，yaml中的热加载函数，定义在该类中
    """

    def read_yaml(self, key, path=Path(BASE_PATH).joinpath(TEMP_FILE)):
        """
        yaml中热加载，顶顶的函数
        :return:
        """
        with open(path, 'r', encoding='utf-8') as f:
            value = yaml.safe_load(f)
            return value[key]

    def random_number(self):
        """
        时间戳
        :return:
        """
        return str(int(time.time()))

    def add(self, a, b):
        return int(a) + int(b)

    def md5_encode(self, data):
        """
        md5,加密算法
        :param data:
        :return:
        """
        # 转为bytes类型数组
        data = str(data).encode(encoding='utf-8')
        md5_data = hashlib.md5(data).hexdigest()
        return md5_data

    def base64_encode(self, data):
        """
        base64,加密方式
        :param data:
        :return:
        """
        data = str(data).encode(encoding='utf-8')
        base64_value = base64.b64encode(data).decode(encoding='utf-8')
        return base64_value

    def create_rsa_key(self):
        """
        生成rsa加密算法的公钥和私钥
        :return:
        """
        (public_key, private_key) = rsa.newkeys(1024)
        with open(BASE_PATH.joinpath(TEMP_PATH).joinpath(Path('public.pem')), 'w+', encoding='utf-8') as f:
            f.write(public_key.save_pkcs1().decode())
        with open(BASE_PATH.joinpath(TEMP_PATH).joinpath('private.pem'), 'w+', encoding='utf-8') as f:
            f.write(private_key.save_pkcs1().decode())

    def rsa_encode(self, data):
        """
        rsa算法：加密数据
        :param data:
        :return:
        """
        with open(BASE_PATH.joinpath(TEMP_PATH).joinpath(Path('public.pem')), 'r', encoding='utf-8') as f:
            public_key = rsa.PublicKey.load_pkcs1(f.read().encode())
        # 将data转为utf-8格式
        data = str(data).encode('utf-8')
        # 将字符串加密为byte类型
        byte_value = rsa.encrypt(data, public_key)
        # 将字符转化为字符串格式
        rsa_value = base64.b64encode(byte_value).decode("utf-8")
        return rsa_value

    def sign_weixin_pay(self, data: dict, wx_key):
        """
        验签：微信支付
            1. 准备好key
            2. 所有发送的数据,非空参数值的参数按照参数名ASCII码从小到大排序（字典序），使用URL键值对的格式（即key1=value1&key2=value2…）拼接成字符串stringA。
        :param wx_key:
        :param data:
        :return:
        """
        new_data = copy.deepcopy(data)
        # 1. 移除非空参数值
        for key, value in data.items():
            if value == '' or key == 'sign':
                new_data.pop(key)

        sort_items = sorted(new_data.items())
        key_value = urllib.parse.urlencode(sort_items)
        # 拼接key
        sign_template = key_value + f'&key={wx_key}'
        # 转为byte类型数组
        sign_byte = sign_template.encode('utf-8')
        # md5加密
        sign_md5 = hashlib.md5(sign_byte).hexdigest()
        # 转为大写
        sign = sign_md5.upper()
        new_data['sign'] = sign
        return new_data

